<?php

namespace app\controllers\pay;

use app\commission\PaidFinish;
use app\controllers\Controller;
use app\controllers\wx\services\Wx;
use app\models\pay\Pay;
use app\models\system\SetPay;
use app\models\system\SetWx;
use app\util\Debug;
use app\util\Request;
use Exception;

class PayController extends Controller
{
    public function actionPrepare()
    {
        $set = SetPay::getLastOne();
        $wx = SetWx::getLastOne(false);

        // order or refill
        $pay_type       = $this->post('pay_type', 1);
        $pay_type_text  = $this->post('pay_type_text', '订单');

        $open_id    = $this->post('openid');
        $sn         = $this->post('sn');
        $amount     = $this->post('amount');
        $amount     = round($amount, 2);
        $body       = $this->post('body', '购买商品');

        $user_id    = $this->post('user_id');

        // wx signature
        // js => window.location.href
        $signature_url = $this->post('signature_url');

        $notify_url = \Yii::$app->request->getHostInfo() . '/pay/pay/callback';

        $params = [
            'p0_Version'            => '1.0',
            'p1_MerchantNo'         => $set->mid,
            'p2_OrderNo'            => $sn,
            'p3_Amount'             => $amount,
            'p4_Cur'                => 1,
            'p5_ProductName'        => $body,
            'p9_NotifyUrl'          => $notify_url,
            'q1_FrpCode'            => 'WEIXIN_GZH',
            'q5_OpenId'             => $open_id,
            'q7_AppId'              => $wx->app_id,
            'qa_TradeMerchantNo'    => $set->bid,
        ];

        try {
            $sign = Sign::signature($params);
            $data   = array_merge($params, [ 'hmac' => md5($sign . $set->secret) ]);
            $url    = 'https://www.joinpay.com/trade/uniPayApi.action';

            $response = Request::post($url, $data);
            $result = json_decode($response, true);

            // 返回100时表示成功
            if ($result['ra_Code'] != 100) {
                throw new Exception('请求支付失败:' . $response);
            }

            // 创建支付订单
            $this->createPayOrder($sn, $amount, $pay_type, $pay_type_text, $user_id);

            // 微信 签名 (需要汇聚这边返回的参数配合, nonceStr, timeStamp)
            $result['rc_Result'] = json_decode($result['rc_Result']);
            $signature = $this->wxSignature($result['rc_Result'], $signature_url);

            return $this->success([
                'amount'    => $result['r3_Amount'],
                'result'    => $result,
                // wx signature
                'signature' => $signature,
            ]);

        } catch (Exception $e) {
            Debug::pay('pay-fail', $e->getMessage());
            return $this->fail('请求支付失败');
        }
    }

    public function actionCallback()
    {
        // 支付状态,  100：支付成功；
        if ($this->get('r6_Status') != 100) {
            return false;
        }

        $params = $this->get();
        // $params = $_GET;

        $sn     = $this->get('r2_OrderNo');
        $amount = $this->get('r3_Amount');

        $model = Pay::findOne(['sn' => $sn]);
        if ($model && $model->amount == $amount) {

            // $hmac = $this->get('hmac');
            // $set = SetPay::getLastOne();
            // $params = $this->get();
            // unset($params['hmac']);
            // sort($params);
            // $params = Sign::signature($params);
            // $params = md5($params . $set->secret);
            // if ($hmac != $params) {
            //     return 'error';
            // }

            $model->request_params = json_encode($params);

            $model->status = 1;
            $model->save();

            // paid
            PaidFinish::paidRun($model);

            // return hj pay
            return 'success';
        } else {
            Debug::pay('pay-callback-error', json_encode($params));
        }
    }

    // create pay order
    protected function createPayOrder($sn, $amount, $pay_type, $pay_type_text, $user_id)
    {
        $model = new Pay();
        $model->sn = $sn;
        $model->amount = $amount;
        $model->user_id = $user_id;
        $model->status = 0;
        $model->pay_type = $pay_type;
        $model->pay_type_text = $pay_type_text;
        $model->pay_mode = '微信';
        $model->save();
    }

    // wx signature
    public function wxSignature($data, $url)
    {
        $ticket = Wx::getJsapiTicket();

        $string = "jsapi_ticket={$ticket}&noncestr={$data->nonceStr}&timestamp={$data->timeStamp}&url={$url}";

        return sha1($string);
    }
}